package com.zsl.swing.redis.desktop.utils;

import com.zsl.swing.redis.desktop.pool.SchedulePoolUtils;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

public class LongTimeTaskUtils {

    private static final String DELETED_DIR = ConfigUtils.BASE_PATH + "del-keys" + File.separator;

    private static final Map<String, LongTimeTask> processingMap = new ConcurrentHashMap<>();

    static {
        periodDeleteProcessingMap();

    }

    private static void periodDeleteProcessingMap() {
        File folder = new File(DELETED_DIR);
        if(!folder.exists()){
            folder.mkdirs();
        }


        SchedulePoolUtils.schedule(() -> {
            int size = processingMap.size();

            if(size != 0){
                for (Map.Entry<String, LongTimeTask> entry : processingMap.entrySet()) {
                    if(entry.getValue().isCancel()){

                        try{
                            Thread.sleep(2000L);
                        }catch (Exception e){
                            //ignore
                        }
                        processingMap.remove(entry.getKey());
                    }
                }
            }

            System.out.println("scheduled  清空前后数量为：" + size +"," + processingMap.size());

        }, 30L, 60L, TimeUnit.SECONDS);
    }

    public static void put(String taskName, boolean isCancel){
        LongTimeTask task;
        if(processingMap.containsKey(taskName)){
            task = processingMap.get(taskName);
        }else{
            task = new LongTimeTask();
            task.setTaskName(taskName);
            task.setCreateTime(new Date());
        }

        task.setCancel(isCancel);

        processingMap.put(taskName, task);
    }

    public static boolean isCancel(String taskName){
        LongTimeTask longTimeTask = processingMap.get(taskName);

        return longTimeTask == null ? false: longTimeTask.isCancel();
    }


    public static List<LongTimeTask> getProcessingTaskList(){
        List<LongTimeTask> processingList = new ArrayList<>(processingMap.values());

        return processingList.stream().filter(t -> !t.isCancel()).sorted((t1, t2) -> t2.getCreateTime().compareTo(t1.getCreateTime())).collect(Collectors.toList());

    }

    public static void cancel(String taskName){

        put(taskName,true);
    }



    public static String buildDeletedKeysFileNameFullPath(String keyword, String uniqueId){

        String folder = DELETED_DIR + uniqueId + File.separator;

        File f = new File(folder);
        if(!f.exists()){
            f.mkdirs();
        }

        return folder + buildDeletedKeysFileName(keyword);
    }


    public static String buildDeletedKeysFileName(String keyword){
        return "deleted_" + keyword + "_like" + new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()) + ".txt";
    }


    public static void clearDeletedKeyFileAll( String uniqueId){
        File parent = new File(DELETED_DIR + uniqueId + File.separator);

        if(!parent.exists()){
            return;
        }

        File[] files = parent.listFiles();

        for(File f: files){
            String name = f.getName();

            System.out.println("del-keys 下" + name + "删除结果：" + f.delete());
        }

        parent.delete();

    }

    public static void clearDbConfigFileAll(String uniqueId) {
        ConfigUtils.delDbConfigFilesByUniqueId(uniqueId);
    }


    public static class LongTimeTask{
        private String taskName;

        private boolean cancel = false;

        private Date createTime;

        public String getTaskName() {
            return taskName;
        }

        public void setTaskName(String taskName) {
            this.taskName = taskName;
        }

        public boolean isCancel() {
            return cancel;
        }

        public void setCancel(boolean cancel) {
            this.cancel = cancel;
        }

        public Date getCreateTime() {
            return createTime;
        }

        public void setCreateTime(Date createTime) {
            this.createTime = createTime;
        }
    }
}
